<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>艾弗里实验：加法与减法实验对比</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            line-height: 1.6;
            color: #333;
        }
        h1, h2, h3 {
            color: #2c3e50;
        }
        .experiment-container {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            margin-bottom: 30px;
        }
        .experiment-panel {
            flex: 1;
            min-width: 350px;
            border: 1px solid #ddd;
            border-radius: 8px;
            padding: 15px;
            background-color: #f9f9f9;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        }
        .experiment-title {
            background-color: #3498db;
            color: white;
            padding: 10px;
            margin: -15px -15px 15px -15px;
            border-radius: 8px 8px 0 0;
            text-align: center;
        }
        .addition .experiment-title {
            background-color: #2ecc71;
        }
        .subtraction .experiment-title {
            background-color: #e74c3c;
        }
        .controls {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 10px;
            margin-bottom: 15px;
        }
        .control-group {
            margin-bottom: 10px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
        }
        select, button {
            width: 100%;
            padding: 8px;
            border-radius: 4px;
            border: 1px solid #ddd;
        }
        button {
            background-color: #3498db;
            color: white;
            border: none;
            cursor: pointer;
            font-weight: bold;
            transition: background-color 0.3s;
        }
        button:hover {
            background-color: #2980b9;
        }
        .run-btn {
            background-color: #2ecc71;
        }
        .run-btn:hover {
            background-color: #27ae60;
        }
        .reset-btn {
            background-color: #e74c3c;
        }
        .reset-btn:hover {
            background-color: #c0392b;
        }
        canvas {
            width: 100%;
            border: 1px solid #ddd;
            background-color: white;
            margin-top: 10px;
            border-radius: 4px;
        }
        .result-display {
            margin-top: 15px;
            padding: 10px;
            border-radius: 4px;
            background-color: #f0f0f0;
            min-height: 60px;
        }
        .comparison-section {
            margin-top: 40px;
            padding: 20px;
            background-color: #ecf0f1;
            border-radius: 8px;
        }
        .comparison-table {
            width: 100%;
            border-collapse: collapse;
            margin: 20px 0;
        }
        .comparison-table th, .comparison-table td {
            border: 1px solid #ddd;
            padding: 12px;
            text-align: left;
        }
        .comparison-table th {
            background-color: #3498db;
            color: white;
        }
        .comparison-table tr:nth-child(even) {
            background-color: #f2f2f2;
        }
        .highlight {
            background-color: #fffacd;
        }
        .key-point {
            font-weight: bold;
            color: #e74c3c;
        }
        .legend {
            display: flex;
            flex-wrap: wrap;
            gap: 15px;
            margin: 15px 0;
        }
        .legend-item {
            display: flex;
            align-items: center;
            gap: 5px;
        }
        .legend-color {
            width: 15px;
            height: 15px;
            border-radius: 50%;
        }
        .conclusion {
            background-color: #d4edda;
            padding: 15px;
            border-left: 5px solid #28a745;
            margin: 20px 0;
        }
    </style>
</head>
<body>
    <h1>艾弗里实验模拟：加法与减法实验对比</h1>
    
    <div class="experiment-container">
        <!-- 加法实验面板 -->
        <div class="experiment-panel addition">
            <div class="experiment-title">加法实验</div>
            <div class="controls">
                <div class="control-group">
                    <label for="additionExtract">添加提取物:</label>
                    <select id="additionExtract">
                        <option value="none">无</option>
                        <option value="dna">DNA</option>
                        <option value="protein">蛋白质</option>
                        <option value="rna">RNA</option>
                        <option value="polysaccharide">多糖</option>
                    </select>
                </div>
                <div class="control-group">
                    <label for="additionBacteria">细菌类型:</label>
                    <select id="additionBacteria">
                        <option value="rough">R型(非致病)</option>
                        <option value="smooth">S型(致病)</option>
                    </select>
                </div>
            </div>
            <button class="run-btn" id="runAddition">运行加法实验</button>
            <button class="reset-btn" id="resetAddition">重置</button>
            <canvas id="additionCanvas" width="500" height="300"></canvas>
            <div class="result-display" id="additionResult"></div>
        </div>
        
        <!-- 减法实验面板 -->
        <div class="experiment-panel subtraction">
            <div class="experiment-title">减法实验</div>
            <div class="controls">
                <div class="control-group">
                    <label for="subtractionExtract">基础提取物:</label>
                    <select id="subtractionExtract">
                        <option value="dna">DNA</option>
                        <option value="protein">蛋白质</option>
                    </select>
                </div>
                <div class="control-group">
                    <label for="subtractionEnzyme">酶处理:</label>
                    <select id="subtractionEnzyme">
                        <option value="none">无</option>
                        <option value="protease">蛋白酶</option>
                        <option value="dnase">DNA酶</option>
                        <option value="rnase">RNA酶</option>
                    </select>
                </div>
            </div>
            <button class="run-btn" id="runSubtraction">运行减法实验</button>
            <button class="reset-btn" id="resetSubtraction">重置</button>
            <canvas id="subtractionCanvas" width="500" height="300"></canvas>
            <div class="result-display" id="subtractionResult"></div>
        </div>
    </div>
    
    <!-- 图例说明 -->
    <div class="legend">
        <div class="legend-item">
            <div class="legend-color" style="background-color: #8bc34a;"></div>
            <span>R型细菌(非致病)</span>
        </div>
        <div class="legend-item">
            <div class="legend-color" style="background-color: #f44336;"></div>
            <span>S型细菌(致病)</span>
        </div>
        <div class="legend-item">
            <div class="legend-color" style="background-color: #ff9800;"></div>
            <span>转化中的细菌</span>
        </div>
        <div class="legend-item">
            <div class="legend-color" style="background-color: #3f51b5;"></div>
            <span>DNA分子</span>
        </div>
        <div class="legend-item">
            <div class="legend-color" style="background-color: #e91e63;"></div>
            <span>蛋白质分子</span>
        </div>
        <div class="legend-item">
            <div class="legend-color" style="background-color: #4caf50;"></div>
            <span>RNA分子</span>
        </div>
        <div class="legend-item">
            <div class="legend-color" style="background-color: #9c27b0;"></div>
            <span>多糖分子</span>
        </div>
    </div>
    
    <!-- 实验方法比较 -->
    <div class="comparison-section">
        <h2>加法实验与减法实验比较</h2>
        
        <table class="comparison-table">
            <tr>
                <th>比较项目</th>
                <th>加法实验</th>
                <th>减法实验</th>
                <th>在艾弗里实验中的应用</th>
            </tr>
            <tr>
                <td>实验设计</td>
                <td>向R型细菌中添加S型细菌的各种提取物</td>
                <td>用特定酶处理S型细菌提取物，去除特定成分</td>
                <td>两种方法结合使用，互相验证</td>
            </tr>
            <tr>
                <td>关键操作</td>
                <td>分别添加DNA、蛋白质、RNA、多糖等成分</td>
                <td>使用DNA酶、蛋白酶、RNA酶等处理提取物</td>
                <td>加法证明DNA能转化，减法证明只有DNA能转化</td>
            </tr>
            <tr class="highlight">
                <td>实验结果</td>
                <td>只有添加DNA的组出现R→S转化</td>
                <td>只有DNA酶处理破坏转化能力</td>
                <td>双重验证DNA是转化因子</td>
            </tr>
            <tr>
                <td>优势</td>
                <td>直接证明DNA能引起转化</td>
                <td>排除其他物质的可能性</td>
                <td>结论更加严谨可靠</td>
            </tr>
            <tr>
                <td>局限性</td>
                <td>不能完全排除其他微量成分的作用</td>
                <td>酶纯度可能影响结果(当时技术限制)</td>
                <td>通过多种酶交叉验证克服</td>
            </tr>
        </table>
        
        <div class="conclusion">
            <h3>科学结论</h3>
            <p>艾弗里通过<strong class="key-point">加法实验</strong>证明：只有S型细菌的<strong>DNA提取物</strong>能使R型转化为S型。</p>
            <p>通过<strong class="key-point">减法实验</strong>证明：当用<strong>DNA酶</strong>处理提取物后，转化能力消失，而其他酶处理不影响转化。</p>
            <p>这种<strong>双重验证</strong>的方法有力地证明了DNA是遗传物质，而非蛋白质或其他成分。</p>
        </div>
    </div>

    <script>
        // 初始化画布
        const additionCanvas = document.getElementById('additionCanvas');
        const additionCtx = additionCanvas.getContext('2d');
        const subtractionCanvas = document.getElementById('subtractionCanvas');
        const subtractionCtx = subtractionCanvas.getContext('2d');
        
        // 设置画布实际尺寸
        function setupCanvas(canvas) {
            const style = window.getComputedStyle(canvas);
            canvas.width = parseInt(style.width) * 2;
            canvas.height = parseInt(style.height) * 2;
        }
        setupCanvas(additionCanvas);
        setupCanvas(subtractionCanvas);
        
        // 实验状态
        const experiments = {
            addition: {
                state: 'ready',
                bacteria: [],
                molecules: [],
                progress: 0,
                animationId: null,
                result: document.getElementById('additionResult')
            },
            subtraction: {
                state: 'ready',
                bacteria: [],
                molecules: [],
                progress: 0,
                animationId: null,
                result: document.getElementById('subtractionResult')
            }
        };
        
        // 初始化实验
        function initExperiment(type) {
            const exp = experiments[type];
            
            exp.state = 'ready';
            exp.progress = 0;
            exp.bacteria = [];
            exp.molecules = [];
            exp.result.textContent = '';
            
            // 创建细菌
            for (let i = 0; i < 25; i++) {
                exp.bacteria.push({
                    x: 50 + Math.random() * (additionCanvas.width/2 - 100),
                    y: 50 + Math.random() * (additionCanvas.height/2 - 100),
                    type: type === 'addition' 
                        ? document.getElementById('additionBacteria').value 
                        : 'rough',
                    transformed: false,
                    transforming: false,
                    transformProgress: 0
                });
            }
            
            drawExperiment(type);
        }
        
        // 绘制实验场景
        function drawExperiment(type) {
            const exp = experiments[type];
            const canvas = type === 'addition' ? additionCanvas : subtractionCanvas;
            const ctx = type === 'addition' ? additionCtx : subtractionCtx;
            
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            
            // 绘制背景
            ctx.fillStyle = '#f0f8ff';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            // 绘制培养皿
            ctx.strokeStyle = '#999';
            ctx.lineWidth = 2;
            ctx.beginPath();
            ctx.arc(canvas.width/4, canvas.height/4, Math.min(canvas.width, canvas.height)/4 - 20, 0, Math.PI * 2);
            ctx.stroke();
            
            // 绘制培养基
            ctx.fillStyle = 'rgba(200, 230, 255, 0.3)';
            ctx.beginPath();
            ctx.arc(canvas.width/4, canvas.height/4, Math.min(canvas.width, canvas.height)/4 - 22, 0, Math.PI * 2);
            ctx.fill();
            
            // 绘制细菌
            exp.bacteria.forEach(bac => {
                if (bac.type === 'rough') {
                    ctx.fillStyle = bac.transformed ? '#ff9800' : '#8bc34a';
                } else {
                    ctx.fillStyle = '#f44336';
                }
                
                if (bac.transforming) {
                    // 绘制转化中的细菌
                    ctx.beginPath();
                    ctx.arc(bac.x, bac.y, 8 + 2 * Math.sin(exp.progress * 0.1), 0, Math.PI * 2);
                    ctx.fill();
                    
                    // 转化进度环
                    ctx.strokeStyle = '#ff9800';
                    ctx.lineWidth = 2;
                    ctx.beginPath();
                    ctx.arc(bac.x, bac.y, 12, 0, Math.PI * 2 * bac.transformProgress);
                    ctx.stroke();
                } else {
                    ctx.beginPath();
                    ctx.arc(bac.x, bac.y, 8, 0, Math.PI * 2);
                    ctx.fill();
                }
            });
            
            // 绘制分子
            exp.molecules.forEach(mol => {
                if (mol.type === 'dna') {
                    ctx.fillStyle = '#3f51b5';
                    drawDNA(ctx, mol.x, mol.y, 10, exp.progress * 0.05);
                } else if (mol.type === 'protein') {
                    ctx.fillStyle = '#e91e63';
                    drawProtein(ctx, mol.x, mol.y, 10);
                } else if (mol.type === 'rna') {
                    ctx.fillStyle = '#4caf50';
                    drawRNA(ctx, mol.x, mol.y, 10, exp.progress * 0.05);
                } else if (mol.type === 'polysaccharide') {
                    ctx.fillStyle = '#9c27b0';
                    drawPolysaccharide(ctx, mol.x, mol.y, 12);
                }
            });
            
            // 绘制实验状态
            ctx.fillStyle = '#000';
            ctx.font = '14px Arial';
            ctx.fillText(`实验状态: ${getStateText(exp.state)}`, 10, 20);
            
            // 绘制实验类型标签
            ctx.font = '16px Arial';
            ctx.fillStyle = type === 'addition' ? '#2ecc71' : '#e74c3c';
            ctx.fillText(type === 'addition' ? '加法实验' : '减法实验', canvas.width/2 - 50, 20);
        }
        
        // 分子绘制函数
        function drawDNA(ctx, x, y, size, rotation) {
            ctx.save();
            ctx.translate(x, y);
            ctx.rotate(rotation);
            
            ctx.beginPath();
            ctx.moveTo(-size, -size);
            ctx.lineTo(size, size);
            ctx.moveTo(-size, size);
            ctx.lineTo(size, -size);
            ctx.strokeStyle = ctx.fillStyle;
            ctx.lineWidth = 1;
            ctx.stroke();
            
            for (let i = -size + 2; i < size - 2; i += 4) {
                ctx.beginPath();
                ctx.moveTo(i, -i);
                ctx.lineTo(-i, i);
                ctx.stroke();
            }
            
            ctx.restore();
        }
        
        function drawProtein(ctx, x, y, size) {
            ctx.beginPath();
            ctx.arc(x, y, size, 0, Math.PI * 2);
            ctx.fill();
            
            ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)';
            ctx.lineWidth = 1;
            ctx.beginPath();
            ctx.arc(x, y, size * 0.7, 0, Math.PI * 1.5);
            ctx.stroke();
            
            ctx.beginPath();
            ctx.arc(x, y, size * 0.4, Math.PI, Math.PI * 2.5);
            ctx.stroke();
        }
        
        function drawRNA(ctx, x, y, size, rotation) {
            ctx.save();
            ctx.translate(x, y);
            ctx.rotate(rotation);
            
            ctx.beginPath();
            for (let i = -size; i <= size; i++) {
                const yPos = Math.sin(i * 0.3) * 3;
                if (i === -size) {
                    ctx.moveTo(i, yPos);
                } else {
                    ctx.lineTo(i, yPos);
                }
            }
            ctx.strokeStyle = ctx.fillStyle;
            ctx.lineWidth = 1.5;
            ctx.stroke();
            
            for (let i = -size + 3; i < size - 3; i += 6) {
                const yPos = Math.sin(i * 0.3) * 3;
                ctx.beginPath();
                ctx.moveTo(i, yPos);
                ctx.lineTo(i, yPos + (yPos > 0 ? -5 : 5));
                ctx.stroke();
            }
            
            ctx.restore();
        }
        
        function drawPolysaccharide(ctx, x, y, size) {
            ctx.beginPath();
            for (let i = 0; i < 6; i++) {
                const angle = i * Math.PI / 3;
                const px = x + Math.cos(angle) * size;
                const py = y + Math.sin(angle) * size;
                if (i === 0) {
                    ctx.moveTo(px, py);
                } else {
                    ctx.lineTo(px, py);
                }
            }
            ctx.closePath();
            ctx.fill();
            
            ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)';
            ctx.lineWidth = 1;
            for (let i = 0; i < 3; i++) {
                const angle1 = i * 2 * Math.PI / 3;
                const angle2 = angle1 + Math.PI / 3;
                ctx.beginPath();
                ctx.moveTo(
                    x + Math.cos(angle1) * size * 0.7,
                    y + Math.sin(angle1) * size * 0.7
                );
                ctx.lineTo(
                    x + Math.cos(angle2) * size * 0.7,
                    y + Math.sin(angle2) * size * 0.7
                );
                ctx.stroke();
            }
        }
        
        function getStateText(state) {
            switch (state) {
                case 'ready': return '准备就绪';
                case 'running': return '进行中...';
                case 'complete': return '已完成';
                default: return '';
            }
        }
        
        // 运行实验
        function runExperiment(type) {
            const exp = experiments[type];
            if (exp.state !== 'ready') return;
            
            exp.state = 'running';
            exp.progress = 0;
            
            // 准备实验条件
            if (type === 'addition') {
                const extractType = document.getElementById('additionExtract').value;
                const bacteriaType = document.getElementById('additionBacteria').value;
                
                // 添加提取物分子
                if (extractType !== 'none') {
                    for (let i = 0; i < 40; i++) {
                        exp.molecules.push({
                            x: 50 + Math.random() * (additionCanvas.width/2 - 100),
                            y: 50 + Math.random() * (additionCanvas.height/2 - 100),
                            type: extractType,
                            vx: (Math.random() - 0.5) * 0.5,
                            vy: (Math.random() - 0.5) * 0.5
                        });
                    }
                }
            } else {
                const extractType = document.getElementById('subtractionExtract').value;
                const enzymeType = document.getElementById('subtractionEnzyme').value;
                
                // 添加提取物分子
                for (let i = 0; i < 40; i++) {
                    exp.molecules.push({
                        x: 50 + Math.random() * (subtractionCanvas.width/2 - 100),
                        y: 50 + Math.random() * (subtractionCanvas.height/2 - 100),
                        type: extractType,
                        vx: (Math.random() - 0.5) * 0.5,
                        vy: (Math.random() - 0.5) * 0.5,
                        destroyed: enzymeType === 'dnase' && extractType === 'dna'
                    });
                }
            }
            
            // 开始动画
            exp.animationId = requestAnimationFrame(() => animateExperiment(type));
            
            // 设置实验完成时间
            setTimeout(() => {
                exp.state = 'complete';
                showResults(type);
                cancelAnimationFrame(exp.animationId);
                drawExperiment(type);
            }, 5000);
        }
        
        // 动画循环
        function animateExperiment(type) {
            const exp = experiments[type];
            exp.progress++;
            
            // 更新分子位置
            exp.molecules.forEach(mol => {
                if (!mol.destroyed) {
                    mol.x += mol.vx;
                    mol.y += mol.vy;
                    
                    // 边界检查
                    const canvas = type === 'addition' ? additionCanvas : subtractionCanvas;
                    if (mol.x < 50 || mol.x > canvas.width/2 - 50) mol.vx *= -1;
                    if (mol.y < 50 || mol.y > canvas.height/2 - 50) mol.vy *= -1;
                }
            });
            
            // 随机开始转化过程
            if (exp.progress % 30 === 0 && exp.state === 'running') {
                if (type === 'addition') {
                    const extractType = document.getElementById('additionExtract').value;
                    const bacteriaType = document.getElementById('additionBacteria').value;
                    
                    if (extractType === 'dna' && bacteriaType === 'rough') {
                        exp.bacteria.forEach(bac => {
                            if (!bac.transformed && !bac.transforming && Math.random() < 0.05) {
                                bac.transforming = true;
                            }
                        });
                    }
                } else {
                    const extractType = document.getElementById('subtractionExtract').value;
                    const enzymeType = document.getElementById('subtractionEnzyme').value;
                    
                    if (extractType === 'dna' && enzymeType !== 'dnase') {
                        exp.bacteria.forEach(bac => {
                            if (!bac.transformed && !bac.transforming && Math.random() < 0.05) {
                                bac.transforming = true;
                            }
                        });
                    }
                }
            }
            
            // 更新转化中的细菌
            exp.bacteria.forEach(bac => {
                if (bac.transforming && bac.transformProgress < 1) {
                    bac.transformProgress += 0.01;
                    if (bac.transformProgress >= 1) {
                        bac.transforming = false;
                        bac.transformed = true;
                        bac.type = 'smooth';
                    }
                }
            });
            
            drawExperiment(type);
            
            if (exp.state === 'running') {
                exp.animationId = requestAnimationFrame(() => animateExperiment(type));
            }
        }
        
        // 显示实验结果
        function showResults(type) {
            const exp = experiments[type];
            
            if (type === 'addition') {
                const extractType = document.getElementById('additionExtract').value;
                const bacteriaType = document.getElementById('additionBacteria').value;
                
                if (bacteriaType === 'smooth') {
                    exp.result.textContent = '观察到S型细菌生长';
                } else {
                    if (extractType === 'dna') {
                        exp.result.textContent = '成功观察到R型转化为S型细菌，证明DNA能引起转化';
                        // 随机转化一些细菌
                        const transformCount = Math.floor(exp.bacteria.length * 0.3);
                        for (let i = 0; i < transformCount; i++) {
                            const index = Math.floor(Math.random() * exp.bacteria.length);
                            exp.bacteria[index].transformed = true;
                            exp.bacteria[index].type = 'smooth';
                        }
                    } else if (extractType !== 'none') {
                        exp.result.textContent = `未观察到转化，${getExtractName(extractType)}不能引起转化`;
                    } else {
                        exp.result.textContent = '未观察到转化，未添加任何提取物';
                    }
                }
            } else {
                const extractType = document.getElementById('subtractionExtract').value;
                const enzymeType = document.getElementById('subtractionEnzyme').value;
                
                if (extractType === 'dna' && enzymeType === 'dnase') {
                    exp.result.textContent = '未观察到转化，DNA酶处理破坏了转化能力';
                } else if (extractType === 'dna' && enzymeType !== 'dnase') {
                    exp.result.textContent = '观察到R型转化为S型，证明DNA是转化因子';
                    // 随机转化一些细菌
                    const transformCount = Math.floor(exp.bacteria.length * 0.3);
                    for (let i = 0; i < transformCount; i++) {
                        const index = Math.floor(Math.random() * exp.bacteria.length);
                        exp.bacteria[index].transformed = true;
                        exp.bacteria[index].type = 'smooth';
                    }
                } else if (extractType === 'protein') {
                    if (enzymeType === 'protease') {
                        exp.result.textContent = '未观察到转化，蛋白质不是转化因子';
                    } else {
                        exp.result.textContent = '未观察到转化，蛋白质不能引起转化';
                    }
                }
            }
        }
        
        function getExtractName(type) {
            switch (type) {
                case 'dna': return 'DNA';
                case 'protein': return '蛋白质';
                case 'rna': return 'RNA';
                case 'polysaccharide': return '多糖';
                default: return '';
            }
        }
        
        // 事件监听
        document.getElementById('runAddition').addEventListener('click', () => runExperiment('addition'));
        document.getElementById('resetAddition').addEventListener('click', () => initExperiment('addition'));
        document.getElementById('runSubtraction').addEventListener('click', () => runExperiment('subtraction'));
        document.getElementById('resetSubtraction').addEventListener('click', () => initExperiment('subtraction'));
        
        // 初始化
        initExperiment('addition');
        initExperiment('subtraction');
    </script>
</body>
</html>